home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 04 - 1988 / 04.10 Oct 88 / driver stuff / IAC.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-17  |  11.8 KB  |  486 lines  |  [TEXT/MPS ]

  1. /***
  2.  *
  3.  * File:        IAC.c
  4.  *
  5.  * Package:        Inter Application Communications
  6.  *
  7.  * Description:    This is the interface package to the driver for the use of
  8.  *                application programs.
  9.  *
  10.  * Author(s):
  11.  *    FEA        6/19/88
  12.  *
  13.  */
  14.  
  15. # include    <types.h>
  16. # include    <files.h>
  17. # include    <memory.h>
  18. # include    <osutils.h>
  19. # include    <serial.h>
  20. # include    <iac.h>
  21.  
  22. # define    MIN_BLK_SIZE    0xC
  23. # define    DEBUG    false
  24.  
  25. static    short    iac_ref_num;
  26.  
  27. /**
  28.  * Routine: iac_open
  29.  *
  30.  *        The IAC driver is opened by this call and the ioRefNum saved so
  31.  *    it doesn't need to be passed with all calls. A null value is returned
  32.  *    if the open is successful; otherwise the operating system error is
  33.  *    returned.
  34.  */
  35.  
  36. short    iac_open()
  37.  
  38. {
  39. SysEnvRec    theWorld;            /* ALMOST complete knowledge about the world */
  40. THz            s_ZoneP, a_ZoneP;    /* so we can check zone adjacency */
  41. OSErr        the_err;
  42.  
  43. short        result = 0;
  44.  
  45.     the_err = SysEnvirons(1, &theWorld);
  46.     if (theWorld.systemVersion < 0x0420)        /* too early! */
  47.     {
  48.         result = EARLY_SYS;        /* "no multifinder" */
  49.     }
  50.     else
  51.     {
  52.         /*    check for multifinder active by checking if system zone is
  53.             adjacent to application zone, which never happens under
  54.             MultiFinder.
  55.         */
  56.         s_ZoneP = SystemZone();
  57.         a_ZoneP = ApplicZone();
  58.         if ( ((long) s_ZoneP->bkLim + MIN_BLK_SIZE) == (long) a_ZoneP )
  59.         {
  60.             result = EARLY_SYS;        /* zones adjacent - no multifinder */
  61.         }
  62.         else    /* now try to actually open the IAC driver */
  63.         {
  64.             SysBeep(1);
  65.             result = OPENDRIVER("\p.IAC", &iac_ref_num);
  66.         }
  67.     }
  68.  
  69.     return(result);
  70. }
  71.  
  72.  
  73. /**
  74.  * Routine: iac_add_dependency
  75.  *
  76.  *        This is used to inform the IAC driver that a new dependency has been
  77.  *    established and should be added to its internal tables. A null value is
  78.  *    returned if the open is successful; otherwise the operating system error
  79.  *    is returned.
  80.  */
  81.  
  82. short    iac_add_dependency(doc_id, slot_id, hat_check, edition)
  83.     long    *doc_id;    /* identifies the source document (permanent) */
  84.     short    *slot_id;    /* identifies the source document (session) */
  85.     short    *hat_check;    /* extent identifier */
  86.     short    *edition;    /* how many times extent has changed (session) */
  87.  
  88. {
  89. IOParam        the_blk;
  90. OSErr        the_err;
  91.  
  92. struct {
  93.     short    func;
  94.     long    doc_id;
  95.     short    slot_id;
  96.     short    hat_check;
  97.     short    edition;
  98. } my_params;
  99.  
  100. # if DEBUG
  101.     return(the_err=noErr);        /* short circuit for testing without MF */
  102. # endif
  103.  
  104.     my_params.func = 1;                    /* set up private parameter block */
  105.     my_params.doc_id = *doc_id;
  106.     my_params.slot_id = *slot_id;
  107.     my_params.hat_check = *hat_check;
  108.  
  109.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  110.     the_blk.ioRefNum = iac_ref_num;
  111.     the_blk.ioBuffer = &my_params;
  112.     the_blk.ioReqCount = sizeof(my_params);
  113.     the_blk.ioPosMode = fsFromStart;
  114.     the_blk.ioPosOffset = 0;
  115.     the_err = PBWrite(&the_blk.qLink, false);    /* add the dependency */
  116.  
  117.     if (the_err == noErr)        /* update output parameters */
  118.     {
  119.         *doc_id = my_params.doc_id;
  120.         *slot_id = my_params.slot_id;
  121.         *hat_check = my_params.hat_check;
  122.         *edition = my_params.edition;
  123.     }
  124.  
  125.     return(the_err);
  126. }
  127.  
  128.  
  129. /**
  130.  * Routine: iac_complete_dependency
  131.  *
  132.  *        This is used to inform the IAC driver of a document that is interested
  133.  *    in a particular dependency. A null value is returned if the open is
  134.  *    successful; otherwise the operating system error is returned.
  135.  */
  136.  
  137. short    iac_complete_dependency(doc_id, slot_id, hat_check)
  138.     long    *doc_id;    /* identifies the source document (permanent) */
  139.     short    *slot_id;    /* identifies the source document (session) */
  140.     short    *hat_check;    /* extent identifier */
  141.  
  142. {
  143. IOParam        the_blk;
  144. OSErr        the_err;
  145.  
  146. struct {
  147.     short    func;
  148.     long    doc_id;
  149.     short    slot_id;
  150.     short    hat_check;
  151. } my_params;
  152.  
  153. # if DEBUG
  154.     return(the_err=noErr);        /* short circuit for testing without MF */
  155. # endif
  156.  
  157.     my_params.func = 2;                    /* set up private parameter block */
  158.     my_params.doc_id = *doc_id;
  159.     my_params.slot_id = *slot_id;
  160.     my_params.hat_check = *hat_check;
  161.  
  162.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  163.     the_blk.ioRefNum = iac_ref_num;
  164.     the_blk.ioBuffer = &my_params;
  165.     the_blk.ioReqCount = sizeof(my_params);
  166.     the_blk.ioPosMode = fsFromStart;
  167.     the_blk.ioPosOffset = 0;
  168.     the_err = PBWrite(&the_blk.qLink, false);    /* complete the dependency */
  169.  
  170.     if (the_err == noErr)        /* update output parameters */
  171.     {
  172.         *doc_id = my_params.doc_id;
  173.         *slot_id = my_params.slot_id;
  174.         *hat_check = my_params.hat_check;
  175.     }
  176.  
  177.     return(the_err);    
  178. }
  179.  
  180.  
  181. /**
  182.  * Routine: iac_remove_dependency
  183.  *
  184.  *        This is used to inform the IAC driver that a document is no longer
  185.  *    interested in a particular dependency. If the document is the original
  186.  *    source all "targets" will be informed that there is no longer any such
  187.  *    extent; if all targets lose interest the source will be informed that it
  188.  *    no longer needs to update the extent.
  189.  */
  190.  
  191. short    iac_remove_dependency(doc_id, slot_id, hat_check)
  192.     long    doc_id;        /* identifies the source document (permanent) */
  193.     short    slot_id;    /* identifies the source document (session) */
  194.     short    hat_check;    /* extent identifier */
  195.  
  196. {
  197. IOParam        the_blk;
  198. OSErr        the_err;
  199.  
  200. struct {
  201.     short    func;
  202.     long    doc_id;
  203.     short    slot_id;
  204.     short    hat_check;
  205. } my_params;
  206.  
  207. # if DEBUG
  208.     return(the_err=noErr);        /* short circuit for testing without MF */
  209. # endif
  210.  
  211.     my_params.func = 3;                    /* set up private parameter block */
  212.     my_params.doc_id = doc_id;
  213.     my_params.slot_id = slot_id;
  214.     my_params.hat_check = hat_check;
  215.  
  216.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  217.     the_blk.ioRefNum = iac_ref_num;
  218.     the_blk.ioBuffer = &my_params;
  219.     the_blk.ioReqCount = sizeof(my_params);
  220.     the_blk.ioPosMode = fsFromStart;
  221.     the_blk.ioPosOffset = 0;
  222.     the_err = PBWrite(&the_blk.qLink, false);    /* remove the dependency */
  223.  
  224.     return(the_err);    
  225. }
  226.  
  227.  
  228. /**
  229.  * Routine: iac_available_dependency
  230.  *
  231.  *        This sets the indicated extent as the "available extent" to be used
  232.  *    as the source for future defaulted "complete_dependency"  calls.
  233.  */
  234.  
  235. short    iac_available_dependency(doc_id, hat_check)
  236.     long    doc_id;        /* identifies the source document (permanent) */
  237.     short    hat_check;    /* extent identifier */
  238.  
  239. {
  240. IOParam        the_blk;
  241. OSErr        the_err;
  242.  
  243. struct {
  244.     short    func;
  245.     long    doc_id;
  246.     short    hat_check;
  247. } my_params;
  248.  
  249. # if DEBUG
  250.     return(the_err=noErr);        /* short circuit for testing without MF */
  251. # endif
  252.  
  253.     my_params.func = 4;                    /* set up private parameter block */
  254.     my_params.doc_id = doc_id;
  255.     my_params.hat_check = hat_check;
  256.  
  257.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  258.     the_blk.ioRefNum = iac_ref_num;
  259.     the_blk.ioBuffer = &my_params;
  260.     the_blk.ioReqCount = sizeof(my_params);
  261.     the_blk.ioPosMode = fsFromStart;
  262.     the_blk.ioPosOffset = 0;
  263.     the_err = PBWrite(&the_blk.qLink, false);    /* this dependency is now "available" */
  264.  
  265.     return(the_err);    
  266. }
  267.  
  268.  
  269. /**
  270.  * Routine: iac_status
  271.  *
  272.  *        This allows the application program to find out what's going on.
  273.  */
  274.  
  275. short    iac_status(slot_id, vers_id, doc_count, extent_count)
  276.     short    slot_id;        /* identifies the inquiring document (session) */
  277.     short    *vers_id;        /* driver version*100 */
  278.     short    *doc_count;        /* count of active documents */
  279.     short    *extent_count;    /* count of extents relevant to inquiring doc */
  280.  
  281. {
  282. IOParam        the_blk;
  283. OSErr        the_err;
  284.  
  285. struct {
  286.     short    func;
  287.     short    slot_id;
  288.     short    vers_id;
  289.     short    doc_count;
  290.     short    extent_count;
  291. } my_params;
  292.  
  293. # if DEBUG
  294.     return(the_err=noErr);        /* short circuit for testing without MF */
  295. # endif
  296.  
  297.     my_params.func = 5;                    /* set up private parameter block */
  298.     my_params.slot_id = slot_id;
  299.  
  300.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  301.     the_blk.ioRefNum = iac_ref_num;
  302.     the_blk.ioBuffer = &my_params;
  303.     the_blk.ioReqCount = sizeof(my_params);
  304.     the_blk.ioPosMode = fsFromStart;
  305.     the_blk.ioPosOffset = 0;
  306.     the_err = PBRead(&the_blk.qLink, false);    /* read IAC status */
  307.  
  308.     if (the_err == noErr)        /* update output parameters */
  309.     {
  310.         *vers_id = my_params.vers_id;
  311.         *doc_count = my_params.doc_count;
  312.         *extent_count = my_params.extent_count;
  313.     }
  314.  
  315.     return(the_err);
  316. }
  317.  
  318.  
  319. /**
  320.  * Routine: iac_census
  321.  *
  322.  *        This provides identifying info for all registered extents.
  323.  */
  324.  
  325. short    iac_census(extent_count, extent_info)
  326.     short        *extent_count;    /* count of extents registered */
  327.     info_tblP    extent_info;    /* Ptr to table of info for each extent */
  328.  
  329. {
  330. IOParam        the_blk;
  331. OSErr        the_err;
  332. short        i;
  333.  
  334. struct {
  335.     short        func;
  336.     short        extent_count;
  337.     info_rec    extent_info[MAX_EXTS];
  338. } my_params;
  339.  
  340. # if DEBUG
  341.     return(the_err=noErr);        /* short circuit for testing without MF */
  342. # endif
  343.  
  344.     my_params.func = 6;                    /* set up private parameter block */
  345.  
  346.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  347.     the_blk.ioRefNum = iac_ref_num;
  348.     the_blk.ioBuffer = &my_params;
  349.     the_blk.ioReqCount = sizeof(my_params);
  350.     the_blk.ioPosMode = fsFromStart;
  351.     the_blk.ioPosOffset = 0;
  352.     the_err = PBRead(&the_blk.qLink, false);    /* read IAC status */
  353.  
  354.     if (the_err == noErr)    /* update output parameters */
  355.     {
  356.         *extent_count = my_params.extent_count;
  357.         BlockMove (&my_params.extent_info[0],
  358.                    (Ptr) extent_info,
  359.                    (long) my_params.extent_count * sizeof(info_rec));
  360.     }
  361.  
  362.     return(the_err);
  363. }
  364.  
  365.  
  366. /**
  367.  * Routine: iac_write_data
  368.  *
  369.  *        This updates the data for the specified extent, resulting in a new
  370.  *    change level.
  371.  */
  372.  
  373. short    iac_write_data(doc_id, hat_check, edition, fmt_count, ext_data)
  374.     long    doc_id;        /* identifies the source document (permanent) */
  375.     short    hat_check;    /* extent identifier */
  376.     short    *edition;    /* how many times extent has changed (session) */
  377.     short    fmt_count;    /* number of formats being written */
  378.     Handle    ext_data;    /* Handle to actual data */
  379.  
  380. {
  381. IOParam        the_blk;
  382. OSErr        the_err;
  383.  
  384. struct {
  385.     short    func;
  386.     long    doc_id;
  387.     short    hat_check;
  388.     short    edition;
  389.     short    fmt_count;
  390.     Handle    the_dataH;
  391. } my_params;
  392.  
  393. # if DEBUG
  394.     return(the_err=noErr);        /* short circuit for testing without MF */
  395. # endif
  396.  
  397.     my_params.func = 7;                    /* set up private parameter block */
  398.     my_params.doc_id = doc_id;
  399.     my_params.hat_check = hat_check;
  400.     my_params.fmt_count = fmt_count;
  401.     my_params.the_dataH = ext_data;
  402.  
  403.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  404.     the_blk.ioRefNum = iac_ref_num;
  405.     the_blk.ioBuffer = &my_params;
  406.     the_blk.ioReqCount = sizeof(my_params);;
  407.     the_blk.ioPosMode = fsFromStart;
  408.     the_blk.ioPosOffset = 0;
  409.     the_err = PBWrite(&the_blk.qLink, false);    /* update dependency */
  410.  
  411.     if (the_err == noErr)        /* update output parameters */
  412.     {
  413.         *edition = my_params.edition;
  414.     }
  415.  
  416.     return(the_err);
  417. }
  418.  
  419.  
  420. /**
  421.  * Routine: iac_read_data
  422.  *
  423.  *        This is used to retrieve the actual data for the latest change_level
  424.  *    for the specified extent. The IAC driver will record that the inquiring
  425.  *    document has read the data.
  426.  *
  427.  *    ext_data will be resized by the driver to hold the data.
  428.  */
  429.  
  430. short    iac_read_data(doc_id, slot_id, hat_check, edition, fmt_pref,
  431.                   fmt_code, ext_data)
  432.     long    doc_id;            /* identifies the source document (permanent) */
  433.     short    slot_id;        /* identifies the source document (session) */
  434.     short    hat_check;        /* extent identifier */
  435.     short    *edition;        /* how many times extent has changed (session) */
  436.     long    fmt_pref[3];    /* preferred formats, descending desirability */
  437.     long    *fmt_code;        /* format returned to caller */
  438.     Handle    ext_data;        /* Handle to actual data */
  439.  
  440. {
  441. IOParam        the_blk;
  442. OSErr        the_err;
  443.  
  444. struct {
  445.     short    func;
  446.     long    doc_id;
  447.     short    slot_id;
  448.     short    hat_check;
  449.     short    edition;
  450.     long    fmt_pref[3];
  451.     long    fmt_code;
  452.     Handle    ext_data;
  453. } my_params;
  454.  
  455. # if DEBUG
  456.     return(the_err=noErr);        /* short circuit for testing without MF */
  457. # endif
  458.  
  459.     my_params.func = 8;                    /* set up private parameter block */
  460.     my_params.doc_id = doc_id;
  461.     my_params.slot_id = slot_id;
  462.     my_params.hat_check = hat_check;
  463.     my_params.edition = *edition;
  464.     my_params.fmt_pref[0] = fmt_pref[0];
  465.     my_params.fmt_pref[1] = fmt_pref[1];
  466.     my_params.fmt_pref[2] = fmt_pref[2];
  467.     my_params.ext_data = ext_data;
  468.  
  469.     the_blk.ioCompletion = nil;            /* set up driver parameter block */
  470.     the_blk.ioRefNum = iac_ref_num;
  471.     the_blk.ioBuffer = &my_params;
  472.     the_blk.ioReqCount = sizeof(my_params);
  473.     the_blk.ioPosMode = fsFromStart;
  474.     the_blk.ioPosOffset = 0;
  475.     the_err = PBRead(&the_blk.qLink, false);    /* read the data */
  476.  
  477.     if (the_err == noErr)
  478.     {
  479.         *edition = my_params.edition;
  480.         *fmt_code = my_params.fmt_code;
  481.     }
  482.  
  483.     return(the_err);
  484. }
  485.  
  486.